#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <time.h>
#include "config.h"

static const char* wndbrg	= "brg"		;
static const char* wndseuil	= "seuil"	;
static const char* wndhsv	= "hsv"		;
static const char* wdnresulth= "h"	;
static const char* wdnresults= "s"	;
static const char* wdnresultv= "v"	;

static int traitercouleurs(IplImage* brgFrame)
{
	//Copies de l’image pour les transformations…
	IplImage* seuilFrame	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 1 );
	IplImage* hsvFrame 		= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* hsvFrame2h	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* hsvFrame2s	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* hsvFrame2v	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* resultFrameh	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* resultFrames	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	IplImage* resultFramev	= cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
	
	//Conversion BGR -> HSV
	cvCvtColor( brgFrame, hsvFrame, CV_BGR2HSV );
	//Pour chaque pixel…
	int x;
	int y;
	for(y = 0; y < (cvGetSize(hsvFrame).height); y++) 
	{
		for(x = 0; x < (cvGetSize(hsvFrame).width); x++) 
		{
			int val_H = (hsvFrame->imageData + hsvFrame->widthStep*y)[x*3  ];
			int val_S = (hsvFrame->imageData + hsvFrame->widthStep*y)[x*3+1];
			int val_V = (hsvFrame->imageData + hsvFrame->widthStep*y)[x*3+2];
			
			(hsvFrame2h->imageData + hsvFrame2h->widthStep*y)[ x*3  ] = val_H;
			(hsvFrame2h->imageData + hsvFrame2h->widthStep*y)[ x*3+1] = 0;
			(hsvFrame2h->imageData + hsvFrame2h->widthStep*y)[ x*3+2] = 0;
			
			(hsvFrame2s->imageData + hsvFrame2s->widthStep*y)[ x*3  ] = val_H;
			(hsvFrame2s->imageData + hsvFrame2s->widthStep*y)[ x*3+1] = 0;
			(hsvFrame2s->imageData + hsvFrame2s->widthStep*y)[ x*3+2] = 0;
			
			(hsvFrame2v->imageData + hsvFrame2v->widthStep*y)[ x*3  ] = val_H;
			(hsvFrame2v->imageData + hsvFrame2v->widthStep*y)[ x*3+1] = 0;
			(hsvFrame2v->imageData + hsvFrame2v->widthStep*y)[ x*3+2] = 0;
			
			(seuilFrame->imageData + seuilFrame->widthStep*y)[x] = 0;
			
			if( (val_H >=-85 && val_H <=-75) ||	//rouge violacé : -85 à -75 (-90 à -75 pour plus grande plage)
				(val_H >=0 && val_H <=10) ) 	//rouge orangé  : -15 à 15
			{
				(hsvFrame2h->imageData + hsvFrame2h->widthStep*y)[ x*3+1] = val_S;
				(hsvFrame2h->imageData + hsvFrame2h->widthStep*y)[ x*3+2] = val_V;
				
				if (val_S<=0) // || val_S>=96 )// && val_S>=-96)	//peu grisé : saturation <= 0 et >=-96 mais pour récupérer plus de valeurs : juste <= 0
				{
					(hsvFrame2s->imageData + hsvFrame2s->widthStep*y)[ x*3+1] = val_S;
					(hsvFrame2s->imageData + hsvFrame2s->widthStep*y)[ x*3+2] = 255;
					(hsvFrame2v->imageData + hsvFrame2v->widthStep*y)[ x*3+1] = val_S;
					
					if ( val_V<=0 ) // || val_V>=96)// && val_V >=-96) // image suffisemment claire : valeur <= 0 et valeur >=-96 mais pour récupérer plus de valeurs : juste <= 0
				    {
						(seuilFrame->imageData + seuilFrame->widthStep*y)[ x    ] = 255;
						(hsvFrame2v->imageData + hsvFrame2v->widthStep*y)[ x*3+2] = val_V;
				    }
				}
			}
		}
	} //fin des boucles
	cvCvtColor( hsvFrame2h, resultFrameh, CV_HSV2RGB );
	cvCvtColor( hsvFrame2s, resultFrames, CV_HSV2RGB );
	cvCvtColor( hsvFrame2v, resultFramev, CV_HSV2RGB );
	cvCvtColor( resultFrameh, resultFrameh, CV_RGB2BGR );
	cvCvtColor( resultFrames, resultFrames, CV_RGB2BGR );
	cvCvtColor( resultFramev, resultFramev, CV_RGB2BGR );
    cvShowImage( wndbrg		, brgFrame		);
    cvShowImage( wndseuil	, seuilFrame	);
    cvShowImage(wdnresulth	, resultFrameh	);
    cvShowImage(wdnresults	, resultFrames	);
    cvShowImage(wdnresultv	, resultFramev	);
	//Libérer l’espace des images
	cvReleaseImage( &seuilFrame	);
	cvReleaseImage( &hsvFrame	);
	cvReleaseImage( &hsvFrame2h	);
	cvReleaseImage( &hsvFrame2s	);
	cvReleaseImage( &hsvFrame2v	);
	cvReleaseImage( &resultFrameh);
	cvReleaseImage( &resultFrames);
	cvReleaseImage( &resultFramev);
    return 0;
}

int test5seuil(int argc, char** argv)
{
	IplImage* brgFrame;
    cvNamedWindow( wndbrg		, 2);
    cvNamedWindow( wndseuil		, 2);
    cvNamedWindow( wdnresulth	, 2);
    cvNamedWindow( wdnresults	, 2);
    cvNamedWindow( wdnresultv	, 2);
	cvMoveWindow(wndbrg		,   0,  500);
	cvMoveWindow(wndseuil	, 600,  500);
	cvMoveWindow(wdnresulth	,   0,  0);
	cvMoveWindow(wdnresults	, 300,  0);
	cvMoveWindow(wdnresultv	, 600,  0);
	//cvMoveWindow(wdnresult	, 600,  500);
	if (argc != 1)
	{
    	double timestamp;
    	double timestamp2;
    	CvCapture* camera;
    	if (argc == 2)
    	{
			//Définir une caméra
			camera = cvCaptureFromCAM( -1 );
            printf("<test5seuil> : caméra\n");
    	}
    	else
    	{
			char nomFilm[40] = "";
			strcat(nomFilm, folder);
			strcat(nomFilm, film);
			//Récupérer des captures provenant d'une vidéo
			//camera = cvCreateFileCapture( nomFilm );
			camera = cvCaptureFromFile( nomFilm );
            printf("<test5seuil> : vidéo : %s\n", nomFilm);
    	}
		timestamp = (double)clock()/CLOCKS_PER_SEC; // get current time in seconds
        for(;;)
        {
			//Capturer une image
			cvGrabFrame( camera );
			//Aller chercher l’image sous format IplImage
			brgFrame 		= cvRetrieveFrame( camera );
			traitercouleurs(brgFrame);
            if( cvWaitKey(10) >= 0 )
                break;
            timestamp2 = (double)clock()/CLOCKS_PER_SEC;
            printf("<test5seuil> : temps entre deux images : %f\n", timestamp2 - timestamp);
            timestamp = timestamp2;
        }
		//Libérer la caméra
		cvReleaseCapture( &camera	);
		//////cvReleaseImage( &brgFrame ); ////// Not release brgFrame !!!!!!!!!!!!!!!!
	}
	else
	{
		int numImage;
		for( numImage = 0; names[numImage] != 0; numImage++ )
	    {
			char nomImage[40] = "";
	        int touche;
			strcat(nomImage, folder);
			strcat(nomImage, names[numImage]);
	    	brgFrame		= cvLoadImage( nomImage, 1 );
	        if( !brgFrame )
	        {
	            printf("<test5seuil> Couldn't load %s\n", names[numImage] );
	            continue;
	        }
			traitercouleurs(brgFrame);
	    	touche = cvWaitKey(0);
	        if( (char)touche == 27 )
	            break;
			cvReleaseImage( &brgFrame);
	    }
	}
	
    cvDestroyWindow( wndbrg		);
    cvDestroyWindow( wndseuil	);
    cvDestroyWindow( wdnresulth	);
    cvDestroyWindow( wdnresults	);
    cvDestroyWindow( wdnresultv	);
	return 0;
}